package com.cyy.common.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyy.common.constant.CacheKey;
import com.cyy.common.constant.Constants;
import com.cyy.common.constant.EmailTemplateType;
import com.cyy.common.constant.EmailType;
import com.cyy.common.exception.ProcessException;
import com.cyy.common.pojo.dto.EmailDto;
import com.cyy.common.pojo.dto.EmailSendDto;
import com.cyy.common.pojo.entity.EmailConfig;
import com.cyy.common.pojo.entity.EmailTemplate;
import com.cyy.common.service.EmailConfigService;
import com.cyy.common.service.EmailService;
import com.cyy.common.service.EmailTemplateService;
import com.cyy.common.utils.CaptchaUtils;
import com.cyy.common.utils.EmailUtils;
import com.cyy.common.utils.RedisUtils;
import com.cyy.common.utils.SelfStringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Slf4j
@Service
@RequiredArgsConstructor
public class EmailServiceImpl implements EmailService {


    private final EmailConfigService emailConfigService;

    private final EmailTemplateService emailTemplateService;

    private final RedisUtils redisUtils;


    @Override
    public void sendRegisterCode(String email) {
        EmailConfig one = Optional.ofNullable(emailConfigService.getOne(Wrappers.<EmailConfig>lambdaQuery()
                        .eq(EmailConfig::getType, EmailType.SYSTEM)
                        .last(Constants.LIMIT_1)
                ))
                .orElseThrow(() -> new ProcessException("未找到指定邮箱配置信息"));
        EmailDto emailDto = new EmailDto();
        emailDto.setHost(one.getSmtpAddress())
                .setUserName(one.getUsername())
                .setPassword(one.getPassword())
                .setPort(one.getSmtpPort())
                .setEncoding("UTF-8");
        JavaMailSenderImpl mailSender = EmailUtils.generateSender(emailDto);

        EmailTemplate emailTemplate = Optional.ofNullable(emailTemplateService.getOne(Wrappers.<EmailTemplate>lambdaQuery()
                .eq(EmailTemplate::getType, EmailTemplateType.USER_REGISTER)
                .last(Constants.LIMIT_1)
        )).orElseThrow(() -> new ProcessException("未找到对应模板信息，请确认模板是否配置"));

        EmailSendDto emailSendDto = new EmailSendDto();
        emailSendDto.setMailSender(mailSender)
                .setSubject(emailTemplate.getSubject())
                .setFrom(emailTemplate.getSender())
                .setTo(email)
                .setSendDate(new Date())
                .setIsHtml(emailTemplate.getIsHtml());

        // 验证码生成
        Map<String, String> map;
        try {
            CaptchaUtils.CodeEntity codeEntity = CaptchaUtils.generateCodeMath();
            String code = codeEntity.getCode();
            redisUtils.set(String.join(Constants.COLON, CacheKey.USER_REGISTER, email), code, 10 * 60);
            map = new HashMap<>();
            map.put("#{code}", code);
        } catch (IOException e) {
            throw new ProcessException("验证码生成失败!");
        }

        // 模板替换处理
        emailSendDto.setTemplate(SelfStringUtils.templateStrReplace(map, emailTemplate.getTemplate()));


        EmailUtils.sendEmail(emailSendDto);

    }
}
